<template>
  <div>
    <div style="margin-bottom: 30px;">
      自定义时间:
      <el-time-select
        v-model="startTime"
        placeholder="起始时间"
        :picker-options="{
          start: '08:00',
          step: '01:00',
          end: '23:59',
        }"
      />
      <el-time-select
        v-model="endTime"
        placeholder="结束时间"
        :picker-options="{
          start: '08:00',
          step: '01:00',
          end: '23:59',
          minTime: startTime
        }"
        @change="changeEndTime"
      />
      <el-select v-model="timeInterval" placeholder="请选择" @change="timeIntervalchange">
        <el-option
          v-for="item in timeIntervalOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
      <span>{{ startTime }}-{{ endTime }}</span>
      <span>分钟数：{{ totalMin }}@@@@{{ perMin }}</span>
    </div>
    <div class="slide-ruler">
      <div v-for="time of timeList" :key="time" class="scale">{{ time }}</div>
    </div>
    <draggable
      v-model="rows"
      class="row sortable-list"
      animation="300"
      handle=".mover"
      @end="end"
    >

      <div
        v-for="(row,index) in rows"
        :key="row.index"
        class="sortable"
        @click.stop="clickChoose(row) "
      >
        <span class="mover">+</span>
        <span>{{ index+1 }}</span>
        <div class="slide-list">
          <div class="slide-ruler-item">
            <div v-for="time of timeList" :key="time" class="scale-item" />
          </div>
          <div ref="slideBox" class="slide-box">
            <draggable
              :list="row.items"
              :group="{ name: 'row' }"
              class="row-item"
              :move="onMove"
              handle=".mover-item"
              @start="start($event,rows)"
              @end="end(rows)"
              @choose="choose"
              @add="add"
              @update="update"
              @unchoose="unchoose"
              @change="change"
              @input="draggableInput"
            >
              <div
                v-for="(item, key) of row.items"
                :key="item.id"
                ref="slideBoxItem"
                class="slide-box-item"
                :style="`width: ${item.width}%; left: ${item.left}%; background: ${itemBGcolor[ key % 2 ]}`"
                @click.stop="timeBlock(row.fid, key, item)"
              >
                <!-- <i class="mover" style="background: #FFFFFF;">{{ key }}</i> -->
                <i v-show="item.changeTimeShow && iShow === key" class="i-left-class i-class" @mousedown.stop="checkI('left', $event, row.fid, key, item, row.items)" />
                <div class="mover-item">{{ item.id }}</div>
                <i v-show="item.changeTimeShow && iShow === key" class="i-right-class i-class" @mousedown.stop="checkI('right', $event, row.fid, key, item, row.items)" />
              </div>
            </draggable>
          </div>
        </div>

      </div>
    </draggable>
    <div style="margin-top: 30px;">{{ rows }}</div>
  </div>
</template>
<script>
import draggable from 'vuedraggable'
import BigNumber from 'bignumber.js'

export default {
  name: 'TwoLists',
  display: 'Two Lists',
  order: 1,
  components: {
    draggable
  },
  data() {
    return {
      startTime: '08:00',
      endTime: '17:00',
      rows: [],
      // 时间刻度（小时）
      timeList: [],
      // 声明的DOM对象
      domObj: {},
      // 左右i的显示
      iShow: null,
      // 是否是选中的时间子块
      loop: 0,
      // 存根数据
      stubData: {},
      // 时间间隔颜色
      itemBGcolor: ['#DAA520', '#B22222'],
      // 总分钟
      totalMin: 0,
      // 每分钟
      perMin: 0,
      timeIntervalOptions: [{
        value: '60',
        label: '小时'
      }, {
        value: '30',
        label: '半小时'
      }, {
        value: '15',
        label: '15分钟'
      }],
      timeInterval: '60'
    }
  },
  created() {
    this.getData()
  },
  methods: {
    getData() {
      this.changeEndTime()
      this.totalMin = this.getMinutesBetween(this.startTime, this.endTime)
      this.domObj = {
        width: 0, // 宽度
        left: 0, // 左偏移量
        changeTimeShow: false // 控制时间显示与时间调整
      }
      this.rows = [
        {
          index: 1,
          fid: 0,
          items: [
            { id: '001',
              'startH': 8,
              'startM': 30,
              'endH': 9,
              'endM': 2,
              startTime: '08:30',
              endTime: '09:30',
              'changeTimeShow': false
            }

          ]
        },
        {
          index: 2,
          fid: 1,
          items: [
            { id: '002', 'changeTimeShow': false, startTime: '09:00',
              endTime: '10:11' },
            { id: '003',
              // 'startH': 13,
              // 'startM': 38,
              // 'endH': 18,
              // 'endM': '04',
              'changeTimeShow': false,
              startTime: '10:20',
              endTime: '10:58'
            }
          ]
        }
      ]
      this.initData()
    },
    // 初始数据过滤
    async initData() {
      // 检查是否有满足条件的startTime和endTime
      const hasInvalidTime = this.rows.some((item) => {
        const { items } = item
        return items.some((subItem) => {
          const { startTime, endTime } = subItem
          return startTime < this.startTime || endTime > this.endTime
        })
      })

      if (hasInvalidTime) {
        console.log('时间范围错误,请修改自定义时间')
        return
      }
      const totalWidth = new BigNumber(100)
      const totalMin = new BigNumber(this.totalMin)
      this.perMin = totalWidth.div(totalMin).dp(4).toNumber()
      this.rows.forEach((group) => {
        group.items.forEach((item) => {
          const itemMin = new BigNumber(this.getMinutesBetween(this.startTime, item.startTime))
          const itemWidth = new BigNumber(this.getMinutesBetween(item.startTime, item.endTime))
          const perMin1 = new BigNumber(this.perMin)
          item.left = `${itemMin.times(perMin1).dp(4).toNumber()}`
          item.width = `${itemWidth.times(perMin1).dp(4).toNumber()}`
        })
      })
    },
    // 子块节点的单击
    timeBlock(code, key, item) {
      console.log(code, key, item, '@子块节点的单击@')
      clearTimeout(this.loop)
      // if (this.loop !== 0) {

      // }
      this.iShow = key
      this.stubData = JSON.parse(JSON.stringify(item))
      // 找到对应的节点，根据条件把对应节点打开或者关闭，但是其它节点要全部关闭
      this.rows.map((v, i) => {
        v.items.map((val, j) => {
          if (v.fid === code && j === key) {
            item.changeTimeShow = !item.changeTimeShow
            this.itemStart = item.startTime
            this.itemEnd = item.endTime
          } else {
            this.rows[i].items[j].changeTimeShow = false
          }
        })
      })
      return false
    },
    // 选中的左右小方块
    checkI(type, e, code, key, item, arr) {
      console.log(type, e, code, key, item, arr, '&*@@@@选中的左右小方块')
      this.loop = setTimeout(() => {
        this.loop = 0
        const selfWidth = e.target.parentNode.clientWidth// 子滑块的宽px
        const selfLeft = e.target.parentNode.offsetLeft// 子滑块的宽px
        const parentWidth = this.$refs.slideBox[0].clientWidth// slideBox轨道总长
        console.log('父级宽度：', parentWidth, selfWidth)
        const disX = e.clientX
        const blockLeft = item.left// 左边偏移量left
        const blockWidth = item.width// 子滑块的宽%
        // item.changeTimeShow = false
        // console.log(item,'--->>>>>',this.stubData)
        // console.log('type==>>点击的那个',type, e, key, item, arr)
        const arrCopy = JSON.parse(JSON.stringify(arr))
        // 对需要移动的子块的所在数组重新按照left大小排序
        function sortLeft(a, b) {
          return a.left - b.left
        }
        arrCopy.sort(sortLeft)
        console.log(arrCopy, '@arrCopy$pai')
        // 处理左右滑动的范围
        let leftL = 0 // 往左滑动的范围
        let leftR = 100 // 往右滑动的范围
        let mark = 0
        for (let i = 0; i < arrCopy.length; i++) {
          if (arrCopy[i].left === item.left) {
            mark = i
            break
          }
        }
        if (arrCopy.length === 1) {
          leftL = 0 // 往左滑动的范围
          leftR = 100 // 往右滑动的范围
        } else {
          if (mark === 0) {
            leftL = 0 // 往左滑动的范围
            leftR = arrCopy[mark + 1].left // 往右滑动的范围
          } else if (mark === arrCopy.length - 1) {
            leftL = arrCopy[mark - 1].left + arrCopy[mark - 1].width
            leftR = 100
          } else if (mark !== 0 && mark < arrCopy.length - 1) {
            leftL = arrCopy[mark - 1].left + arrCopy[mark - 1].width
            leftR = arrCopy[mark + 1].left
          }
        }
        // console.log('arrCopy==',arrCopy,'==mark=',mark,'=leftL=',leftL,'=leftR=',leftR)
        // 子块鼠标移动事件
        document.onmousemove = (e) => {
          // console.log(blockWidth, '子块滑动事件', e.clientX, '--==-运算的-', e.clientX - disX, '---left=', blockLeft + (e.clientX - disX))
          const parentWidth1 = new BigNumber(parentWidth)
          const slidWidth = new BigNumber(e.clientX - disX)
          const blockLeft1 = new BigNumber(blockLeft)
          const blockWidth1 = new BigNumber(blockWidth)
          const tempPercent = slidWidth.div(parentWidth1).times(100).dp(4).toNumber()
          const tempPercent1 = new BigNumber(tempPercent)
          const perMin = new BigNumber(this.perMin)
          const comMin = tempPercent1.idiv(perMin).toNumber()
          console.log(tempPercent, 'tempPercent', comMin)
          if (type === 'left') {
            const leftWidth0 = blockLeft1.plus(tempPercent1).dp(4).toNumber()
            const leftWidth1 = blockWidth1.minus(tempPercent1).dp(4).toNumber()
            if (leftWidth0 < leftL) {
              item.left = leftL
            } else if (leftWidth1 >= 0.5) {
              item.left = blockLeft1.plus(tempPercent1).dp(4).toNumber()
              item.width = leftWidth1
            }
            console.log('left@@', item.width, item.left)
            item.startTime = this.conversionhs(comMin, this.itemStart)
          } else if (type === 'right') {
            const leftR1 = new BigNumber(leftR)
            // const newWidth = leftR1.minus(blockLeft1).dp(4).toNumber()
            const newWidth = leftR1.minus(blockLeft1).dp(4).toNumber()
            item.width = blockWidth1.plus(tempPercent1).dp(4).toNumber()
            if (item.width >= newWidth) {
              item.width = newWidth
            } else if (item.width <= 0.5) {
              item.width = 0.5
            }
            console.log('right@@', item.width)
            // item.endTime = this.conversionhs(comMin, this.itemEnd)
          }
        }
        // 左右小方块的鼠标抬起事件
        document.onmouseup = (e) => {
          this.iShow = null
          console.log('item左右小方块的鼠标抬起事件', item.width)
          if (item.width <= 0) {
            this.rows[code].items.splice(key, 1)
          }
          item.startTime = item.startTime1
          document.onmousemove = null
          document.onmouseup = null
        }
      }, 200)
      return false
    },
    // 分钟 换算 时,分
    conversionhs(timeNum, Basetime) {
      console.log('timeNum', timeNum, Basetime)
      let newTimeStr
      const [hour, minute] = Basetime.split(':')
      console.log(Basetime, '###')
      const timeInMinutes = parseInt(hour, 10) * 60 + parseInt(minute, 10)
      console.log('timeNum', timeNum, Basetime, timeInMinutes)
      if (timeNum > 0) {
        const newTimeInMinutes = timeInMinutes + 40
        const newHour = Math.floor(newTimeInMinutes / 60)
        const newMinute = newTimeInMinutes % 60
        newTimeStr = `${newHour.toString().padStart(2, '0')}:${newMinute.toString().padStart(2, '0')}`
      } else {
        const newTimeInMinutes = timeInMinutes - Math.abs(timeNum)
        const newHour = Math.floor(newTimeInMinutes / 60)
        const newMinute = newTimeInMinutes % 60
        newTimeStr = `${newHour.toString().padStart(2, '0')}:${newMinute.toString().padStart(2, '0')}`
      }
      return newTimeStr
    },

    start(e, val) {
      console.log(e, 'start', val)
      this.baseRows = []
      this.baseRows = JSON.parse(JSON.stringify(val))
    },
    end(val) {
      const aa = this.checkTimeConflicts(this.rows)
      if (aa) {
        this.rows = this.rows.filter(row => row.items.length > 0)
      } else {
        console.log('时间冲突')
        this.rows = this.baseRows
      }
      // console.log(e.item._underlying_vm_, 'start', e)
      // const saveList = []
      // const beforeList = this.list.filter((item) => {
      //   return item.refRouteId === e.from.firstChild.attributes[1].nodeValue
      // })[0]
      // const afterList = this.list.filter((item) => {
      //   return item.refRouteId === e.to.firstChild.attributes[1].nodeValue
      // })[0]
      console.log(this.rows, aa, val)

      // if(){}
      // console.log(this.rows, aa)
    },
    onMove(e, originalEvent) {
      console.log(e)
      console.log(originalEvent, 'originalEvent')
      // false表示阻止拖拽
      return true
    },
    choose() {
      // console.log(e, '鼠标点击选中要拖拽元素时的事件')
    },
    clickChoose(e) {
      console.log(e, '鼠标点击选中要拖拽元素')
    },
    add(e) {
      console.log(e, 'add')
    },
    update(e) {
      console.log(e, 'update')
    },
    unchoose(e) {
      console.log(e, 'unchoose')
    },
    sort(e) {
      console.log(e, 'sort')
    },
    // 被拖动的元素数据及被拖入后的下标
    change(e) {
      console.log(e, 'change')
      // this.dragNode = {
      //   data: event.added.element,
      //   newIndex: event.added.newIndex
      // }
    },
    // 拖入之后 draggable组件中的数据
    draggableInput(e) {
      console.log(e, 'input')
    },
    copyMouseenter(e) {
      console.log(e, 'eee')
    },
    // x选定结束时间
    changeEndTime() {
      // const timeArray = this.generateTimeArray(this.startTime, this.endTime)
      const timeArray = this.generateMinTimeArray(this.startTime, this.endTime, '60')
      console.log(timeArray.length)
      this.totalMin = this.getMinutesBetween(this.startTime, this.endTime)
      this.initData()
      this.timeList = timeArray
    },
    timeIntervalchange(e) {
      console.log(e)
      this.timeList = this.generateMinTimeArray(this.startTime, this.endTime, e)
    },
    // 以每小时生成数组
    generateTimeArray(startTime, endTime) {
      const timeArray = []
      let currentHour = parseInt(startTime.split(':')[0])
      while (currentHour <= parseInt(endTime.split(':')[0])) {
        const timeString = `${currentHour.toString().padStart(2, '0')}:00`
        timeArray.push(timeString)
        currentHour++
      }

      return timeArray
    },
    //  以每分钟生成数组
    // generateMinTimeArray1(startTime, endTime) {
    //   const startParts = startTime.split(':')
    //   const endParts = endTime.split(':')
    //   const startHour = parseInt(startParts[0])
    //   const startMinute = parseInt(startParts[1])
    //   const endHour = parseInt(endParts[0])
    //   const endMinute = parseInt(endParts[1])
    //   const totalStartMinutes = startHour * 60 + startMinute
    //   const totalEndMinutes = endHour * 60 + endMinute
    //   const timeArray = []
    //   for (let i = totalStartMinutes; i <= totalEndMinutes; i++) {
    //     const hour = Math.floor(i / 60)
    //     const minute = i % 60
    //     const timeString = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`
    //     timeArray.push(timeString)
    //   }
    //   return timeArray
    // },
    // 以每分钟生成数组
    generateMinTimeArray(startTime, endTime, min) {
      const interval = Number(min)// 时间间隔为30分钟
      const timeArray = []
      let currentTime = startTime
      while (currentTime <= endTime) {
        timeArray.push(currentTime)
        let [hour, minute] = currentTime.split(':').map(Number)
        minute += interval
        if (minute >= 60) {
          hour += Math.floor(minute / 60)
          minute %= 60
        }
        currentTime = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`
      }
      return timeArray
    },
    generateMinTimeArray15(startTime, endTime) {
      const interval = 15 // 时间间隔为15分钟
      const timeArray = []
      let currentTime = startTime
      while (currentTime <= endTime) {
        timeArray.push(currentTime)
        let [hour, minute] = currentTime.split(':').map(Number)
        minute += interval
        if (minute >= 60) {
          hour += Math.floor(minute / 60)
          minute %= 60
        }
        currentTime = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`
      }
      return timeArray
    },

    // 开始时间到结束时间 算出多少分钟
    getMinutesBetween(startTime, endTime) {
      const startParts = startTime.split(':')
      const endParts = endTime.split(':')

      const startHour = parseInt(startParts[0])
      const startMinute = parseInt(startParts[1])

      const endHour = parseInt(endParts[0])
      const endMinute = parseInt(endParts[1])

      const totalStartMinutes = startHour * 60 + startMinute
      const totalEndMinutes = endHour * 60 + endMinute

      return totalEndMinutes - totalStartMinutes
    },

    // 判断时间区间是否重复
    checkTimeConflicts(data) {
      // 遍历每个时间段集合
      for (let i = 0; i < data.length; i++) {
        const items1 = data[i].items
        // 遍历该集合中的每个时间段
        for (let j = 0; j < items1.length; j++) {
          const startTime1 = items1[j].startTime
          const endTime1 = items1[j].endTime
          // 再遍历一次集合，但只检查后面的时间段
          for (let k = j + 1; k < items1.length; k++) {
            const startTime2 = items1[k].startTime
            const endTime2 = items1[k].endTime
            // 如果两个时间段有重叠部分，则返回错误信息
            if (
              (startTime1 >= startTime2 && startTime1 < endTime2) ||
          (endTime1 > startTime2 && endTime1 <= endTime2)
            ) {
              console.log(`时间段 ${j + 1} 和时间段 ${k + 1} 存在冲突`)
              return false
            }
          }
        }
      }
      // 时间段没有冲突，返回 null
      return true
    }

  }
}
</script>
<style scoped lang="scss">
.sortable{
  // width: 810px;
  width: 100%;
  display: flex;
  align-items: end;
  background: red;
  margin-bottom: 8px;
  padding: 5px;
}
.sortable-list{
  height: 100%;
  background: grey;
  padding: 5px 15px;
}
.row-item{
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  box-flex: 1
}
// 刻度
.slide-ruler {
  position: relative;
  left: 0px;
  // width: 730px;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-left:28px ;
  padding-right: 20px;
}
.slide-ruler-item {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: 0px;
  // width: 730px;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 99;
}
.scale {
  text-align: center;
  width: 15px;
  font-size: 12px;
}
.scale-item {
  text-align: center;
  width: 2px;
  height: 18px;
  border-radius: 9px;
  background: #008B8B;
}
.slide-list {
  // width: 720px;
  position: relative;
  width: 100%;
}
.slide-box {
  width: 100%;
  height: 20px;
  background: 	#483D8B;
  display: flex;
  position: relative;
}
.slide-box-item {
  height: 100%;
  position: absolute;
  z-index: 999;
  padding: 0 5px;
  box-sizing: border-box;
}
.mover-item{
  display: inline-block;
  width: 100%;
  height: 20px;
}
.i-class{
  width: 20px;
  height: 20px;
  position: absolute;
  display: inline-block;
  background: greenyellow;
  background-position: -5px;
  z-index: 1;
}
.i-left-class{
  left: -3px;
}
.i-right-class{
  right: -3px;
}
.i-class:hover{
  cursor:w-resize
}
.timeHover {
  width: 100%;
  height: 100%;
  display: inline-block;
}

</style>
